﻿using LxBasic;
using LxCore;
using System.Diagnostics;
using System.Security.Cryptography;

namespace LxCore
{
    public class ConnectWallOneSide : ConnectWallBase
    {
        (double a21, double a24, double b2)[] Factors;
        public override void CheckCreate(FvJoint joint)
        {
            base.CheckCreate(joint);
            CheckCreator.ArrayStrict(ref Factors, ConFaces.Length);
        }
        public void SetConnect(EquationWithTransTerm OMatrix, EquationWithTransTerm NMatrix, IField<double> Source_b, IField<double> Source_a)
        {
            setMatrix(OMatrix, NMatrix);
            this.Source_b = Source_b;
            this.Source_a = Source_a;
        }

        public override void FormAbOnFaces(ThreadInfo threadInfo)
        {
            var O_con = O_Matrix.GetConnectWallFactor(Joint.OBound);
            var N_con = N_Matrix.GetConnectWallFactor(Joint.NBound);
            (int i1, int endp1) = Joint.FaceIdx.Split(threadInfo);
            var sou_b = Source_b.GetFaceVarArr(Joint);
            var sou_a = Source_a.GetFaceVarArr(Joint);
            var osides = O_Matrix.Zone.BouFaces;
            for (; i1 < endp1; i1++)
            {
                ref FvJoiFace j = ref ConFaces[i1];
                double area = osides[j.O_BouFace].Area;
                var ofactor = O_con.GetFactor(j.O_BouFace);
                var nfactor = N_con.GetFactor(j.N_BouFace);
                PairMatrix pm = new PairMatrix()
                {
                    a11 = ofactor.a11,
                    a12 = ofactor.a12,
                    b1 = ofactor.b1,
                    a21 = ofactor.a21,
                    a22 = ofactor.a22,
                    b2 = ofactor.b2,
                    a44 = nfactor.a11,
                    a43 = nfactor.a12,
                    b4 = nfactor.b1,
                    a34 = nfactor.a21,
                    a33 = nfactor.a22,
                    b3 = nfactor.b2,
                };
                pm.a31 = pm.a21;
                pm.a24 = pm.a34;
                pm.a22 = pm.a33 = pm.a22 + pm.a33 - sou_a.GetFaceVar(i1) * area;
                pm.b2 = pm.b3 = pm.b2 + pm.b3 + sou_b.GetFaceVar(i1) * area;
                pm.Eliminate_a12a43();
                O_con.SetFactor(j.O_BouFace, pm.a11, pm.b1);
                N_con.SetFactor(j.N_BouFace, pm.a44, pm.b4);
                A14[i1] = pm.a14;
                A41[i1] = pm.a41;
                this.Factors[i1] = (pm.a21 / pm.a22, pm.a24 / pm.a22, pm.b2 / pm.a22);
            }
        }

        public override void UpdateJointValue(ThreadInfo threadInfo)
        {
            (int i1, int endp1) = Joint.FaceIdx.Split(threadInfo);
            for (; i1 < endp1; i1++)
            {
                ref var f = ref Factors[i1];
                ref FvJoiFace pair = ref ConFaces[i1];
                O_XBou[pair.O_BouFace] = N_XBou[pair.N_BouFace] = f.b2
                                 - f.a21 * O_XInn[pair.O_InnCell]
                                 - f.a24 * N_XInn[pair.N_InnCell];
            }
        }
    }

}
//var ofs = O_Matrix.FactorsToCalBouCell;
//var nfs = N_Matrix.FactorsToCalBouCell;
//if (Joint.IsConode)
//{
//    (int i1, int endp1) = Joint.FaceIdx.Split(threadInfo);
//    for (; i1 < endp1; i1++)
//    {
//        ref FvJointFace pair = ref Joints[i1];
//        O_XInn[pair.O_BouFace] = N_XInn[pair.N_BouFace] = ofs[pair.O_BouFace].b
//                         - ofs[pair.N_BouFace].a * O_XInn[pair.O_InnCell]
//                         - nfs[pair.N_BouFace].a * N_XInn[pair.N_InnCell];
//    }

//}
//public override void FormAbOnJointFaces(ThreadInfo threadInfo)
//{
//    var O_Factors = O_Matrix.FactorsToCalBouCell;
//    double[] O_ABouO = O_Matrix.BouA;
//    double[] O_ABouN = O_Matrix.ABouNShare;
//    //double[] O_b = O_Matrix.B;
//    double[] O_BouFaceShare = O_Matrix.BouFaceShare;
//    var N_Factors = N_Matrix.FactorsToCalBouCell;
//    double[] N_ABouO = N_Matrix.BouA;
//    double[] N_ABouN = N_Matrix.ABouNShare;
//    //double[] N_b = N_Matrix.B;
//    double[] N_BouFaceShare = N_Matrix.InnFaceShare;
//    if (Joint.IsConode)
//    {
//        (int i1, int endp1) = Joint.FaceIdx.Split(threadInfo);
//        var sou_b = Source_b.GetFaceVars(Joint);
//        var sou_a = Source_a.GetFaceVars(Joint);
//        var osides = O_Matrix.Zone.BouCFaces;
//        for (; i1 < endp1; i1++)
//        {
//            ref FvJointFace j = ref Joints[i1];
//            double area = osides[j.O_BouFace].Area;
//            //ref FvFace oface = ref O_Faces[j.O_Face];
//            ref double OA_bc = ref O_ABouN[j.O_BouFace];
//            ref double OA_bb = ref O_Factors[j.O_BouFace].a;
//            ref double OB_b = ref O_Factors[j.O_BouFace].b;
//            ref double NA_bc = ref N_ABouN[j.N_BouFace];
//            ref double NA_bb = ref N_Factors[j.N_BouFace].a;
//            ref double NB_b = ref O_Factors[j.N_BouFace].b;
//            PairMatrix pm = new PairMatrix();
//            pm.a12 = O_ABouO[j.O_BouFace]; pm.a11 = -OA_bc;
//            pm.a21 = pm.a31 = OA_bc;
//            pm.a22 = pm.a33 = OA_bb + NA_bb - sou_a.GetFaceVar(i1) * area;
//            pm.b2 = pm.b3 = OB_b + NB_b + sou_b.GetFaceVar(i1) * area;
//            pm.a24 = pm.a34 = NA_bc;
//            pm.a43 = N_ABouO[j.N_BouFace]; pm.a44 = -NA_bc;
//            pm.Eliminate_a12a43();
//            A14[i1] = pm.a14;
//            A41[i1] = pm.a41;
//            OA_bc = -pm.a11;
//            O_BouFaceShare[j.O_BouFace] += pm.b1;
//            NA_bc = -pm.a44;
//            N_BouFaceShare[j.N_BouFace] += pm.b4;
//            OA_bb = pm.a21 / pm.a22;
//            OB_b = pm.b2 / pm.a22;
//            NA_bb = pm.a24 / pm.a22;
//        }
//    }
//}
